package IR;

/**
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Date;

import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.analysis.standard.StandardAnalyzer;
import org.apache.lucene.document.Document;
import org.apache.lucene.index.IndexReader;
import org.apache.lucene.queryParser.QueryParser;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.ScoreDoc;
import org.apache.lucene.search.TopDocs;
import org.apache.lucene.store.FSDirectory;
import org.apache.lucene.util.Version;

/** Simple command-line based search demo. */
public class SearchFiles {

  private SearchFiles() {}

  public static String[][] Search(String str, String field) throws Exception {
    String index = "index";
    String queries = null;
    boolean raw = false;
    String queryString = null;
    String[][] result = null;

    IndexReader reader = IndexReader.open(FSDirectory.open(new File(index)));
    IndexSearcher searcher = new IndexSearcher(reader);
    Analyzer analyzer = new Analyseur();

    BufferedReader in = null;
    if (queries != null) {
      in = new BufferedReader(new InputStreamReader(new FileInputStream(queries), "UTF-8"));
    } else {
      in = new BufferedReader(new InputStreamReader(System.in, "UTF-8"));
    }
    QueryParser parser = new QueryParser(Version.LUCENE_31, field, analyzer);

      str = str.trim();
      if (str.length() != 0) {
          Query query = parser.parse(str);
          System.out.println("Searching for: " + query.toString(field));

        result = doPagingSearch(in, searcher, query, str, field);
      }
    searcher.close();
    reader.close();
    return result;
  }


  /**
   * This demonstrates a typical paging search scenario, where the search engine presents 
   * pages of size n to the user. The user can then go to the next page if interested in
   * the next hits.
   * 
   * When the query is executed for the first time, then only enough results are collected
   * to fill 5 result pages. If the user wants to page beyond this limit, then the query
   * is executed another time and all hits are collected.
   * 
   */
  private static ArrayList doList(String req)
  {
    int last = 0;
    String tmp;
    ArrayList wordlist = new ArrayList();
    while (last != -1 && req.length() != 0)
    {
        last = req.indexOf("\n");
        if (last == -1 || (last > req.indexOf(" ") && req.indexOf(" ") != -1))
            last = req.indexOf(" ");
        if (last == -1)
        {
            if (req.charAt(req.length() - 1) == '\n')
                tmp = req.substring(0, req.length() - 1);
            else
                tmp = req.substring(0);
            if (!wordlist.contains(tmp))
                wordlist.add(tmp);
        }
        else
        {
            tmp = req.substring(0, last);
            if (tmp.length() != 0)
            {
                if (tmp.charAt(tmp.length() - 1) == '\n')
                    tmp = tmp.substring(0, tmp.length() - 1);
                if (!wordlist.contains(tmp))
                    wordlist.add(tmp);
            }
            req = req.substring(last + 1);
        }
    }
    return wordlist;
  }
  public static String[][] doPagingSearch(BufferedReader in, IndexSearcher searcher, Query query, String req, String field) throws IOException {
 
    TopDocs results = searcher.search(query, 200);
    ScoreDoc[] hits = results.scoreDocs;
    
    int numTotalHits = results.totalHits;
    System.out.println(numTotalHits + " total matching documents");
    int length = Math.min(hits.length, numTotalHits);
    ArrayList wordlist = doList(req);
    String[][] result = new String[length][4];
    ArrayList contentlist;
    int j = 0;
    int count = 0;
    for (int i = 0; i < length; i++)
    {
        Document doc = searcher.doc(hits[i].doc);
        String name = doc.get("name");
        contentlist = doList(doc.get(field));
        j = 0;
        count = 0;
        while (j < wordlist.size())
        {
            if (contentlist.contains(wordlist.get(j)))
                count++;
            j++;
        }
        double aa = count;
        double bb = wordlist.size();
        double cc = contentlist.size();
        System.out.println();
        result[i][0] = String.valueOf(aa / (bb - aa + cc));
        if (name != null) {
          result[i][1] = name;
          if (doc.get("path") != null)
            result[i][3] = doc.get("path");
          String owner = doc.get("owner");
          if (owner != null)
            result[i][2] = owner;
        }
        else
        {
          System.out.println((i+1) + ". " + "No name for this document");
        }
    }
    int i = 0;
    j = 1;
    String[] tmp = new String[4];
    while (i < length)
    {
        j = i + 1;
        while (j < length)
        {
            if (Float.parseFloat(result[i][0]) < Float.parseFloat(result[j][0]))
            {
                tmp[0] = result[j][0];
                tmp[1] = result[j][1];
                tmp[2] = result[j][2];
                tmp[3] = result[j][3];
                result[j][0] = result[i][0];
                result[j][1] = result[i][1];
                result[j][2] = result[i][2];
                result[j][3] = result[i][3];
                result[i][0] = tmp[0];
                result[i][1] = tmp[1];
                result[i][2] = tmp[2];
                result[i][3] = tmp[3];
            }
            j++;
        }
        i++;
    }
    return result;
  }
}
